package avicit.bdp.dcs.utils.api;

import avicit.bdp.common.dto.api.KeyValue;
import avicit.bdp.dcs.utils.api.enums.Key;
import avicit.bdp.dcs.utils.api.enums.Method;
import avicit.bdp.dcs.utils.api.request.RequestAdapter;
import avicit.bdp.dcs.utils.api.request.RequestAdapterUtil;
import avicit.platform6.core.exception.BusinessException;
import com.alibaba.fastjson2.JSONObject;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

/**
 * @金航数码科技有限责任公司
 * @作者：developer
 * @邮箱：developer@avic-digital.com
 * @创建时间： 2022-02-23 11:48
 * @类说明：
 * @修改记录：
 */
public class HttpUtil {

    private static final Logger LOG = LoggerFactory.getLogger(HttpUtil.class);

    private Configuration readerSliceConfig;

    /**
     * API请求方式
     */
    private String method;

    public HttpUtil(Configuration readerSliceConfig){
        this.readerSliceConfig = readerSliceConfig;
        this.method = this.readerSliceConfig.getString(Key.METHOD);
    }

    /**
     * 远程调用API接口
     */
    public String remoteCallApi() {
        Method method = Method.getMethod(this.method);
        switch (method) {
            case GET:
            case POST:
                return callApi();
            default:
                String msg = String.format("不支持的请求类型%s", this.method);
                LOG.error(msg);
                throw new BusinessException(msg);
        }
    }

    /**
     * API接口调用
     */
    private String callApi(){
        // 构造请求URL
        String url = buildUrl(null);

        LOG.info("url:{}", url);
        LOG.info("call api only once...");

        return callAndParse(url);
    }

    /**
     * 构造请求URL
     */
    private String buildUrl(String startPage) {
        LOG.info("build url...");
        StringBuffer urlBuf = new StringBuffer(readerSliceConfig.getString(Key.URL));

        // 追加请求参数
        appendRequestParams(urlBuf);

        // 支持分页，url追加分页参数
        appendPageParam(urlBuf, startPage);

        // 追加增量参数
        appendIncrementParam(urlBuf);

        return urlBuf.toString();
    }

    /**
     * 追加请求参数
     * @param urlBuf
     */
    private void appendRequestParams(StringBuffer urlBuf) {
        LOG.info("append request param...");
        Method method = Method.getMethod(this.method);
        switch (method) {
            case GET:
                appendGetRequestParams(urlBuf);
                break;
            case POST:
                appendPostRequestParams(urlBuf);
                break;
            default:
                String msg = String.format("不支持的请求类型%s", this.method);
                LOG.error(msg);
                throw new BusinessException(msg);
        }
    }

    /**
     * 追加GET请求参数
     * @param urlBuf
     */
    private void appendGetRequestParams(StringBuffer urlBuf) {
        Configuration requestParam = readerSliceConfig.getConfiguration(Key.REQUEST_PARAM);

        // 处理query参数
        List<KeyValue> queryParamList = requestParam.getList(Key.QUERY_PARAM, KeyValue.class);
        if (!CollectionUtils.isEmpty(queryParamList)) {

            if(!urlBuf.toString().contains(Key.QUESTION_MARK)){
                urlBuf.append(Key.QUESTION_MARK);
            }else{
                urlBuf.append(Key.AND_MARK);
            }

            for(int i = 0; i < queryParamList.size(); i++){
                KeyValue k = JSONObject.parseObject(JSONObject.toJSONString(queryParamList.get(i)), KeyValue.class);
                urlBuf.append(k.getName()).append(Key.EQUAL_SIGN).append(k.getValue());

                if(i < queryParamList.size() - 1){
                    urlBuf.append(Key.AND_MARK);
                }
            }
        }

        // 处理rest参数
        List<KeyValue> restParamList = requestParam.getList(Key.REST_PARAM, KeyValue.class);
        if (!CollectionUtils.isEmpty(restParamList)) {
            for(int i = 0; i < restParamList.size(); i++){
                KeyValue k = JSONObject.parseObject(JSONObject.toJSONString(restParamList.get(i)), KeyValue.class);

                String s = urlBuf.toString().replace(Key.LEFT_BRACKET + k.getName() + Key.RIGHT_BRACKET, k.getValue());
                urlBuf.setLength(0);
                urlBuf.append(s);
            }
        }
    }

    /**
     * 追加POST请求参数
     * @param urlBuf
     */
    private void appendPostRequestParams(StringBuffer urlBuf) {
        appendGetRequestParams(urlBuf);
    }

    /**
     * 追加分页参数
     * @param urlBuf
     */
    private void appendPageParam(StringBuffer urlBuf, String startPage) {
        LOG.info("append page param...");
        boolean havePaging = readerSliceConfig.getBool(Key.HAVE_PAGING, false);
        if(havePaging){
            Configuration pageParam = readerSliceConfig.getConfiguration(Key.PAGE_PARAM);
            String currentPageParamName = pageParam.getString(Key.CURRENT_PAGE_PARAM_NAME);
            String pageSizeParamName = pageParam.getString(Key.PAGE_SIZE_PARAM_NAME);

            if(StringUtils.isEmpty(startPage)){
                startPage = pageParam.getString(Key.START_PAGE);
            }

//            String pageSize = pageParam.getString(Key.PAGE_SIZE);
            String pageSize = "1";
            if(!urlBuf.toString().contains(Key.QUESTION_MARK)){
                urlBuf.append(Key.QUESTION_MARK);
            }else{
                urlBuf.append(Key.AND_MARK);
            }
            urlBuf.append(pageSizeParamName).append(Key.EQUAL_SIGN).append(pageSize).append(Key.AND_MARK);
            urlBuf.append(currentPageParamName).append(Key.EQUAL_SIGN).append(startPage);
        }
    }

    /**
     * 追加增量参数
     * @param urlBuf
     */
    private void appendIncrementParam(StringBuffer urlBuf) {
        LOG.info("append increment param...");
        boolean haveIncrement = readerSliceConfig.getBool(Key.HAVE_INCREMENT, false);
        if(haveIncrement){
            Configuration incrementParam = readerSliceConfig.getConfiguration(Key.INCREMENT_PARAM);
            String startTimeField = incrementParam.getString(Key.START_TIME_FIELD);
            String endTimeField = incrementParam.getString(Key.END_TIME_FIELD);
            String startTime = incrementParam.getString(Key.START_TIME);
            String endTime = incrementParam.getString(Key.END_TIME);

            if(!urlBuf.toString().contains(Key.QUESTION_MARK)){
                urlBuf.append(Key.QUESTION_MARK);
            }else{
                urlBuf.append(Key.AND_MARK);
            }

            urlBuf.append(startTimeField).append(Key.EQUAL_SIGN).append(startTime).append(Key.AND_MARK);
            urlBuf.append(endTimeField).append(Key.EQUAL_SIGN).append(endTime);
        }
    }

    /**
     * 调用并解析结果数据
     * @param url
     * @return
     */
    private String callAndParse(String url) {
        RequestAdapter requestAdapter = RequestAdapterUtil.getRequestAdapter(this.method);
        return requestAdapter.callApi(readerSliceConfig, url);
    }

}
